﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;
using YJKArch.AreaSet;
using YJKArch.Utils;
using YRevitJig;

namespace ModelValidation.ClearHeightCheck
{
	public class ApplicationClearHeight : IExternalApplication
	{
		public Result OnStartup(UIControlledApplication application)
		{
			ApplicationClearHeight.thisApp = this;
			this.m_fun = null;
			this.m_ShowClearHeightForm = null;
			this.m_ShowSetForm = null;
			application.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(this.app_SelTypeMethod);
			application.ControlledApplication.DocumentCreated += new EventHandler<DocumentCreatedEventArgs>(this.app_SelTypeMethod);
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public Result OnShutdown(UIControlledApplication application)
		{
			if (this.m_ShowClearHeightForm != null && this.m_ShowClearHeightForm.Visible)
			{
				this.m_ShowClearHeightForm.Close();
			}
			application.ControlledApplication.DocumentOpened -= new EventHandler<DocumentOpenedEventArgs>(this.app_SelTypeMethod);
			application.ControlledApplication.DocumentCreated -= new EventHandler<DocumentCreatedEventArgs>(this.app_SelTypeMethod);
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private void app_SelTypeMethod(object obj, RevitAPIPostDocEventArgs args)
		{
			List<Element> allElements = new ClearHeightCheckFun(args.Document).getAllElements();
			List<CategoryItem> list = new List<CategoryItem>();
			list = SelectCategrayType.getCategoryItemListFromXML(true);
			SelectCategrayType selectCategrayType = new SelectCategrayType(allElements);
			selectCategrayType.SetCategotyList(list);
			selectCategrayType.initCategoryItemList();
			selectCategrayType.SaveToXmlFile(true);
			list.Clear();
			list = SelectCategrayType.getCategoryItemListFromXML(false);
			selectCategrayType.SetCategotyList(list);
			selectCategrayType.initCategoryItemList();
			selectCategrayType.SaveToXmlFile(false);
		}

		public void CreateClearHeightSetForm(UIApplication app)
		{
			if (this.m_ShowSetForm == null || this.m_ShowSetForm.IsDisposed)
			{
				RequestHandler requestHandler = new RequestHandler();
				ExternalEvent exEvent = ExternalEvent.Create(requestHandler);
				this.m_ShowSetForm = new ClearHeightSetForm(app, exEvent, requestHandler);
				this.m_ShowSetForm.ShowDialog();
				return;
			}
			this.m_ShowSetForm.ShowDialog();
		}

		public void CreateClearHeightForm(ClearHeightCheckFun func, WindowHandle _hWndRevit)
		{
			if (this.m_ShowClearHeightForm == null || this.m_ShowClearHeightForm.IsDisposed)
			{
				this.m_fun = func;
				RequestHandler requestHandler = new RequestHandler();
				ExternalEvent exEvent = ExternalEvent.Create(requestHandler);
				Dictionary<Level, List<ClearHeightArea>> levelItemInfo = new Dictionary<Level, List<ClearHeightArea>>();
				levelItemInfo = this.m_fun.getClearHeightInLevel();
				this.m_ShowClearHeightForm = new ShowClearHeightForm(levelItemInfo, exEvent, requestHandler);
				this.m_ShowClearHeightForm.Show(_hWndRevit);
				this.m_hWndRevit = _hWndRevit;
				return;
			}
			this.m_ShowClearHeightForm.ShowDialog();
		}

		public void ReShowClearHeightForm()
		{
			if (this.m_ShowClearHeightForm == null || this.m_ShowClearHeightForm.IsDisposed)
			{
				return;
			}
			this.m_ShowClearHeightForm.Show(this.m_hWndRevit);
		}

		public void HideClearHeightForm()
		{
			if (this.m_ShowClearHeightForm == null || this.m_ShowClearHeightForm.IsDisposed)
			{
				return;
			}
			this.m_ShowClearHeightForm.Hide();
		}

		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public List<List<CurveLoop>> DrawZoneManual(UIApplication app, WindowHandle _hWndRevit)
		{
			this.m_uiDoc = app.ActiveUIDocument;
			this.m_drawJigCurve = new DrawJigCurve(this.m_uiDoc);
			Document document = this.m_uiDoc.Document;
			Selection selection = this.m_uiDoc.Selection;
			this.m_hWndRevit = _hWndRevit;
			DrawZoneForm drawZoneForm = new DrawZoneForm(this.m_hWndRevit);
			drawZoneForm.Show(this.m_hWndRevit);
			int wMsg = 7;
			ApplicationClearHeight.SendMessage(this.m_hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			List<List<CurveLoop>> list = new List<List<CurveLoop>>();
			this.m_lstCurvesId.Clear();
			TransactionGroup transactionGroup = new TransactionGroup(document, "TransactionGroup");
			transactionGroup.Start();
			XYZ zero = XYZ.Zero;
			this.m_PickLastPoint = null;
			while (this.isRun)
			{
				if (!drawZoneForm.Chain)
				{
					this.m_PickLastPoint = null;
				}
				try
				{
					if (drawZoneForm.m_eDrawMode == DrawMode.Line)
					{
						Result result = this.DrawJigLineRefCurve(drawZoneForm.Chain);
						if (drawZoneForm.m_clickMode)
						{
							drawZoneForm.m_clickMode = false;
							continue;
						}
						if (result == Autodesk.Revit.UI.Result.Cancelled && drawZoneForm.m_eDrawMode == DrawMode.Line && !drawZoneForm.m_clickMode)
						{
							transactionGroup.RollBack();
							drawZoneForm.Close();
							return list;
						}
					}
					else if (DrawMode.Rect == drawZoneForm.m_eDrawMode)
					{
						Result result = this.DrawJigRectRefCurve();
						if (drawZoneForm.m_clickMode)
						{
							drawZoneForm.m_clickMode = false;
							continue;
						}
						if (result == Autodesk.Revit.UI.Result.Cancelled && DrawMode.Rect == drawZoneForm.m_eDrawMode && !drawZoneForm.m_clickMode)
						{
							transactionGroup.RollBack();
							drawZoneForm.Close();
							return list;
						}
					}
					else if (DrawMode.Arc3Pt == drawZoneForm.m_eDrawMode)
					{
						Result result = this.DrawJigArc3PtRefCurve(drawZoneForm.Chain);
						if (drawZoneForm.m_clickMode)
						{
							drawZoneForm.m_clickMode = false;
							continue;
						}
						if (result == Autodesk.Revit.UI.Result.Cancelled && DrawMode.Arc3Pt == drawZoneForm.m_eDrawMode && !drawZoneForm.m_clickMode)
						{
							transactionGroup.RollBack();
							drawZoneForm.Close();
							return list;
						}
					}
					else if (DrawMode.ArcCenter == drawZoneForm.m_eDrawMode)
					{
						Result result = this.DrawJigArcCenterRefCurve();
						if (drawZoneForm.m_clickMode)
						{
							drawZoneForm.m_clickMode = false;
							continue;
						}
						if (result == Autodesk.Revit.UI.Result.Cancelled && DrawMode.ArcCenter == drawZoneForm.m_eDrawMode && !drawZoneForm.m_clickMode)
						{
							transactionGroup.RollBack();
							drawZoneForm.Close();
							return list;
						}
					}
					else
					{
						if (DrawMode.Delete == drawZoneForm.m_eDrawMode)
						{
							this.m_PickLastPoint = null;
							DetailCurveFilter detailCurveFilter = new DetailCurveFilter();
							IEnumerable<Element> enumerable = selection.PickElementsByRectangle(detailCurveFilter, "请框选需要删除的面积边线");
							Transaction transaction = new Transaction(document, "DeleteElements");
							transaction.Start();
							foreach (Element element in enumerable)
							{
								this.m_lstCurvesId.Remove(element.Id);
								document.Delete(element.Id);
							}
							transaction.Commit();
							continue;
						}
						if (DrawMode.Finish == drawZoneForm.m_eDrawMode)
						{
							this.m_PickLastPoint = null;
							List<Curve> list2 = new List<Curve>();
							foreach (ElementId elementId in this.m_lstCurvesId)
							{
								DetailCurve detailCurve = document.GetElement(elementId) as DetailCurve;
								list2.Add(detailCurve.GeometryCurve);
							}
							bool flag = true;
							List<RichPoint> list3 = this.ConstructRichPointSet(list2);
							using (List<RichPoint>.Enumerator enumerator3 = list3.GetEnumerator())
							{
								while (enumerator3.MoveNext())
								{
									if (enumerator3.Current.m_curves.Count < 2)
									{
										flag = false;
										break;
									}
								}
							}
							if (!flag)
							{
								YJKMessageBox.Show("区域不闭合。");
								drawZoneForm.m_eDrawMode = drawZoneForm.GetChecked();
								continue;
							}
							list3.Sort(new RichPointComparer());
							List<ClosedArea> closedAreas = this.GetClosedAreas(list3);
							Transaction transaction2 = new Transaction(document, "CreateFilledRegion");
							transaction2.Start();
							document.Delete(this.m_lstCurvesId);
							transaction2.Commit();
							foreach (ClosedArea closedArea in closedAreas)
							{
								list.Add(closedArea.getCurveLoopList());
							}
							transactionGroup.Assimilate();
							drawZoneForm.Close();
							return list;
						}
					}
					if (this.IsClosed(document, this.m_lstCurvesId))
					{
						this.m_PickLastPoint = null;
					}
					continue;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					if (drawZoneForm.m_clickMode)
					{
						drawZoneForm.m_clickMode = false;
						continue;
					}
					transactionGroup.RollBack();
					drawZoneForm.Close();
					return list;
				}
				catch (Exception)
				{
					continue;
				}
				return list;
			}
			transactionGroup.RollBack();
			return list;
		}

		private string GetstatusPromptWithLine(int index)
		{
			string result = "选择直线的起点";
			if (index % 2 == 1)
			{
				result = "选择直线的终点";
			}
			return result;
		}

		private Result DrawJigLineRefCurve(bool bIsContinuous)
		{
			try
			{
				List<Curve> lstCurves = new List<Curve>();
				if (!bIsContinuous)
				{
					this.m_PickLastPoint = null;
				}
				Result result = this.m_drawJigCurve.DrawJigCurveLine(ref lstCurves, ref this.m_PickLastPoint, this.GetstatusPromptWithLine(0), this.GetstatusPromptWithLine(1));
				if (result != null)
				{
					return result;
				}
				if (!bIsContinuous)
				{
					this.m_PickLastPoint = null;
				}
				this.DrawLines(lstCurves);
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private bool IsContinuous(bool isContinuous)
		{
			return isContinuous && this.m_PickLastPoint != null;
		}

		private string GetstatusPromptWithBox(int index)
		{
			string result = "选择矩形的起点";
			if (index % 2 == 1)
			{
				result = "选择矩形的终点";
			}
			return result;
		}

		private Result DrawJigRectRefCurve()
		{
			this.m_PickLastPoint = null;
			try
			{
				List<Curve> lstCurves = new List<Curve>();
				Result result = this.m_drawJigCurve.DrawJigCurveRect(ref lstCurves, this.GetstatusPromptWithBox(0), this.GetstatusPromptWithBox(1));
				if (result != null)
				{
					return result;
				}
				this.DrawLines(lstCurves);
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private string GetstatusPromptWithArc3Pt(int index)
		{
			string result = "选择弧形的起点";
			if (index % 3 == 1)
			{
				result = "选择弧形的终点";
			}
			else if (index % 3 == 2)
			{
				result = "选择弧形线上点";
			}
			return result;
		}

		private Result DrawJigArc3PtRefCurve(bool bIsContinuous)
		{
			try
			{
				List<Curve> lstCurves = new List<Curve>();
				if (!bIsContinuous)
				{
					this.m_PickLastPoint = null;
				}
				Result result = this.m_drawJigCurve.DrawJigCurveArc3Pt(ref lstCurves, ref this.m_PickLastPoint, this.GetstatusPromptWithArc3Pt(0), this.GetstatusPromptWithArc3Pt(1), this.GetstatusPromptWithArc3Pt(2));
				if (result != null)
				{
					return result;
				}
				if (!bIsContinuous)
				{
					this.m_PickLastPoint = null;
				}
				this.DrawLines(lstCurves);
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		private string GetstatusPromptWithArcCenter(int index)
		{
			string result = "选择弧形墙面定位线的圆心";
			if (index % 3 == 1)
			{
				result = "选择弧形墙面定位线的起始点";
			}
			else if (index % 3 == 2)
			{
				result = "选择弧形墙面定位线的终点";
			}
			return result;
		}

		private Result DrawJigArcCenterRefCurve()
		{
			this.m_PickLastPoint = null;
			try
			{
				List<Curve> lstCurves = new List<Curve>();
				Result result = this.m_drawJigCurve.DrawJigCurveArcCenter2Pt(ref lstCurves, this.GetstatusPromptWithArcCenter(0), this.GetstatusPromptWithArcCenter(1), this.GetstatusPromptWithArcCenter(2));
				if (result != null)
				{
					return result;
				}
				this.DrawLines(lstCurves);
			}
			catch (Exception)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			return Autodesk.Revit.UI.Result.Succeeded;
		}

		public bool IsClosed(Autodesk.Revit.DB.Document doc, List<ElementId> ids)
		{
			List<Curve> list = new List<Curve>();
			foreach (ElementId elementId in ids)
			{
				DetailCurve detailCurve = doc.GetElement(elementId) as DetailCurve;
				list.Add(detailCurve.GeometryCurve);
			}
			string empty = string.Empty;
			return this.SerializeCurves(list, ref empty);
		}

		public bool SerializeCurves(List<Curve> curves, ref string message)
		{
			if (curves.Count == 0)
			{
				message = "曲线数量为0";
				return false;
			}
			Dictionary<XYZ, List<Curve>> dictionary = new Dictionary<XYZ, List<Curve>>(new XYZEqualityComparer());
			foreach (Curve curve in curves)
			{
				XYZ endPoint = curve.GetEndPoint(0);
				XYZ endPoint2 = curve.GetEndPoint(1);
				if (!dictionary.ContainsKey(endPoint))
				{
					dictionary.Add(endPoint, new List<Curve>
					{
						curve
					});
				}
				else
				{
					dictionary[endPoint].Add(curve);
				}
				if (!dictionary.ContainsKey(endPoint2))
				{
					dictionary.Add(endPoint2, new List<Curve>
					{
						curve
					});
				}
				else
				{
					dictionary[endPoint2].Add(curve);
				}
			}
			foreach (KeyValuePair<XYZ, List<Curve>> keyValuePair in dictionary)
			{
				XYZ key = keyValuePair.Key;
				List<Curve> value = keyValuePair.Value;
				if (value.Count > 2)
				{
					message = "所选参照线重叠或者存在分支";
					return false;
				}
				if (value.Count == 1)
				{
					message = "所选参照线不是环线";
					return false;
				}
			}
			return true;
		}

		public List<ClosedArea> GetClosedAreas(List<RichPoint> richPoints)
		{
			List<ClosedArea> list = new List<ClosedArea>();
			while (richPoints.Count > 1)
			{
				List<Curve> list2 = this.SearchLongestPath(richPoints);
				int num = -1;
				if (list.Count > 0)
				{
					ClosedArea closedArea = list[list.Count - 1];
					List<XYZ> list3 = new List<XYZ>();
					foreach (Curve curve in closedArea.m_outerBoundary)
					{
						list3.AddRange(curve.Tessellate());
					}
					XYZ endPoint = list2[0].GetEndPoint(0);
					num = Geometry.PointInPloygon(list3, endPoint, 0.0001, 0.0001);
				}
				if (1 == num)
				{
					list[list.Count - 1].m_innerBoundary.Add(list2);
				}
				else if (-1 == num)
				{
					ClosedArea closedArea2 = new ClosedArea();
					closedArea2.m_outerBoundary = new List<Curve>();
					closedArea2.m_outerBoundary.AddRange(list2);
					closedArea2.m_innerBoundary = new List<List<Curve>>();
					list.Add(closedArea2);
				}
				foreach (Curve curve2 in list2)
				{
					XYZ ptStart = curve2.GetEndPoint(0);
					int num2 = richPoints.FindIndex((RichPoint a) => a.m_point.IsAlmostEqualTo(ptStart));
					if (-1 != num2)
					{
						foreach (Curve curve3 in richPoints[num2].m_curves)
						{
							XYZ ptEnd = curve3.GetEndPoint(1);
							RichPoint richPoint = richPoints.Find((RichPoint a) => a.m_point.IsAlmostEqualTo(ptEnd));
							for (int i = 0; i < richPoint.m_curves.Count; i++)
							{
								if (richPoint.m_curves[i].GetEndPoint(1).IsAlmostEqualTo(ptStart))
								{
									richPoint.m_curves.RemoveAt(i);
									break;
								}
							}
						}
						richPoints.RemoveAt(num2);
					}
				}
				this.DeleteSingleEdgePoint(ref richPoints);
			}
			return list;
		}

		private void DeleteSingleEdgePoint(ref List<RichPoint> richPoints)
		{
			for (int i = 0; i < richPoints.Count; i++)
			{
				RichPoint richPoint = richPoints[i];
				if (1 == richPoint.m_curves.Count)
				{
					XYZ endPoint = richPoint.m_curves[0].GetEndPoint(0);
					XYZ ptEnd = richPoint.m_curves[0].GetEndPoint(1);
					richPoints.RemoveAt(i);
					i--;
					RichPoint richPoint2 = richPoints.Find((RichPoint a) => a.m_point.IsAlmostEqualTo(ptEnd));
					for (int j = 0; j < richPoint2.m_curves.Count; j++)
					{
						if (richPoint2.m_curves[j].GetEndPoint(1).IsAlmostEqualTo(endPoint))
						{
							richPoint2.m_curves.RemoveAt(j);
							if (richPoint2.m_curves.Count == 0)
							{
								richPoints.Remove(richPoint2);
							}
							i = -1;
							break;
						}
					}
				}
			}
			richPoints.TrimExcess();
		}

		private List<Curve> SearchLongestPath(List<RichPoint> richPoints)
		{
			XYZ xyz = XYZ.BasisY.Negate();
			double num = 0.0;
			List<Curve> list = new List<Curve>();
			Curve curve = null;
			XYZ ptCurrent = richPoints[0].m_point;
            //Predicate<RichPoint> <>9__0;
            //do
            //{
            //    Predicate<RichPoint> match;
            //    if ((match = <>9__0) == null)
            //    {
            //        match = (<>9__0 = ((RichPoint a) => a.m_point.IsAlmostEqualTo(ptCurrent)));
            //    }
            //    foreach (Curve curve2 in richPoints.Find(match).m_curves)
            //    {
            //        XYZ tangentAt = this.GetTangentAt(curve2);
            //        double num2 = xyz.AngleOnPlaneTo(tangentAt, XYZ.BasisZ);
            //        if (Math.Round(Math.PI*2, 4) == Math.Round(num2, 4))
            //        {
            //            num2 = 0.0;
            //        }
            //        if (num2 > num)
            //        {
            //            curve = curve2;
            //            num = num2;
            //        }
            //    }
            //    list.Add(curve);
            //    ptCurrent = curve.GetEndPoint(1);
            //    xyz = this.GetTangentAt(this.CreateReversedCurve(curve));
            //    num = 0.0;
            //}
			while (!ptCurrent.IsAlmostEqualTo(richPoints[0].m_point));
			return list;
		}

		private XYZ GetTangentAt(Curve curve)
		{
			return curve.ComputeDerivatives(0.0, true).BasisX.Normalize();
		}

		private void DrawLines(List<Curve> lstCurves)
		{
			foreach (Curve curve in lstCurves)
			{
				DetailCurve detailCurve = this.CreateDetailCurve(this.m_uiDoc.Document, curve);
				if (detailCurve != null)
				{
					this.m_lstCurvesId.Add(detailCurve.Id);
				}
			}
		}

		private DetailCurve CreateDetailCurve(Autodesk.Revit.DB.Document doc, Curve curve)
		{
			int lineColor = YJKArch.AreaSet.Common.RgbColorToInt(System.Drawing.Color.FromArgb(255, 0, 255));
			GraphicsStyle lineStyle = YJKArch.AreaSet.Common.CreateLineStyle(doc, "ClearHeightCurve", 4, lineColor);
			Transaction transaction = new Transaction(doc, "DrawCurve");
			transaction.Start();
			DetailCurve detailCurve = doc.Create.NewDetailCurve(doc.ActiveView, curve);
			detailCurve.LineStyle = lineStyle;
			transaction.Commit();
			return detailCurve;
		}

		public static List<Line> CreateRect(XYZ pt1, XYZ pt2)
		{
			XYZ xyz = new XYZ(pt1.X, pt2.Y, pt1.Z);
			XYZ xyz2 = new XYZ(pt2.X, pt1.Y, pt1.Z);
			return new List<Line>
			{
				Line.CreateBound(pt1, xyz),
				Line.CreateBound(xyz, pt2),
				Line.CreateBound(pt2, xyz2),
				Line.CreateBound(xyz2, pt1)
			};
		}

		public static Arc CreateArc(XYZ ptCenter, XYZ ptArcStart, XYZ ptArcEnd)
		{
			double length = (ptArcStart - ptCenter).GetLength();
			XYZ xyz = ptArcStart - ptCenter;
			XYZ xyz2 = ptArcEnd - ptCenter;
			xyz.AngleOnPlaneTo(xyz2, XYZ.BasisZ);
			double num;
			double num2;
			if (xyz.AngleOnPlaneTo(xyz2, XYZ.BasisZ) <= Math.PI)
			{
				num = XYZ.BasisX.AngleOnPlaneTo(xyz, XYZ.BasisZ);
				num2 = XYZ.BasisX.AngleOnPlaneTo(xyz2, XYZ.BasisZ);
				if (num > num2)
				{
					num2 += Math.PI*2;
				}
				return Arc.Create(ptCenter, length, num, num2, XYZ.BasisX, XYZ.BasisY);
			}
			num = XYZ.BasisX.Negate().AngleOnPlaneTo(xyz, XYZ.BasisZ.Negate());
			num2 = XYZ.BasisX.Negate().AngleOnPlaneTo(xyz2, XYZ.BasisZ.Negate());
			if (num > num2)
			{
				num2 += Math.PI*2;
			}
			return Arc.Create(ptCenter, length, num, num2, XYZ.BasisX.Negate(), XYZ.BasisY);
		}

		public List<RichPoint> ConstructRichPointSet(List<Curve> splitCurves)
		{
			List<RichPoint> list = new List<RichPoint>();
			foreach (Curve curve in splitCurves)
			{
				XYZ ptStart = curve.GetEndPoint(0);
				int num = list.FindIndex((RichPoint a) => a.m_point.IsAlmostEqualTo(ptStart));
				if (-1 == num)
				{
					list.Add(new RichPoint(ptStart, curve));
				}
				else
				{
					list[num].AddCurve(curve);
				}
				XYZ ptEnd = curve.GetEndPoint(1);
				num = list.FindIndex((RichPoint a) => a.m_point.IsAlmostEqualTo(ptEnd));
				if (-1 == num)
				{
					list.Add(new RichPoint(ptEnd, this.CreateReversedCurve(curve)));
				}
				else
				{
					list[num].AddCurve(this.CreateReversedCurve(curve));
				}
			}
			return list;
		}

		private Curve CreateReversedCurve(Curve orig)
		{
			if (orig is Line)
			{
				return Line.CreateBound(orig.GetEndPoint(1), orig.GetEndPoint(0));
			}
			if (orig is Arc)
			{
				return Arc.Create(orig.GetEndPoint(1), orig.GetEndPoint(0), orig.Evaluate(0.5, true));
			}
			throw new Exception("无法创建方向相反的曲线。");
		}

		public List<List<CurveLoop>> GetRoomLoops(UIDocument uidoc)
		{
			List<List<CurveLoop>> list = new List<List<CurveLoop>>();
			new List<Room>();
			foreach (Room room in this.SelectRooms(uidoc))
			{
				List<CurveLoop> item = new List<CurveLoop>();
				item = this.GetWallCurves(room);
				list.Add(item);
			}
			return list;
		}

		private List<Room> SelectRooms(UIDocument uidoc)
		{
			List<Room> list = new List<Room>();
			try
			{
				Document document = uidoc.Document;
				bool flag = this.IsLinkRevitArchDoc(document);
                ObjectType objectType = flag ? (ObjectType)5 : (ObjectType)1;
				foreach (Reference reference in uidoc.Selection.PickObjects(objectType, new RoomSelectionFilter(flag)))
				{
					Room room;
					if (!flag)
					{
						room = (document.GetElement(reference.ElementId) as Room);
					}
					else
					{
						Transform identity = Transform.Identity;
						room = this.GetLinkDocRoomById(document, reference.LinkedElementId, ref identity);
					}
					if (room != null)
					{
						list.Add(room);
					}
				}
			}
			catch
			{
			}
			return list;
		}

		private Room GetLinkDocRoomById(Autodesk.Revit.DB.Document doc, ElementId idRoom, ref Transform transform)
		{
			Room room = null;
			try
			{
				List<RevitLinkInstance> list = new FilteredElementCollector(doc).OfClass(typeof(RevitLinkInstance)).Cast<RevitLinkInstance>().ToList<RevitLinkInstance>();
				IEnumerator<Document> enumerator = (from instance in list
				select instance.GetLinkDocument()).GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						Document docLink = enumerator.Current;
						if (docLink != null)
						{
							room = (docLink.GetElement(idRoom) as Room);
							if (room != null)
							{
								transform = list.Find((RevitLinkInstance e) => e.GetLinkDocument().PathName == docLink.PathName).GetTotalTransform();
								break;
							}
						}
					}
				}
			}
			catch
			{
			}
			return room;
		}

		private bool IsLinkRevitArchDoc(Autodesk.Revit.DB.Document doc)
		{
			return new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms).ToElementIds().Count == 0;
		}

		private List<CurveLoop> GetWallCurves(Room room)
		{
			Document document = room.Document;
			IList<IList<BoundarySegment>> boundarySegments = room.GetBoundarySegments(new SpatialElementBoundaryOptions
			{
                SpatialElementBoundaryLocation = (SpatialElementBoundaryLocation)2
			});
			List<CurveLoop> list = new List<CurveLoop>();
			if (boundarySegments.Count < 1)
			{
				return list;
			}
			IEnumerable<BoundarySegment> enumerable = boundarySegments.First<IList<BoundarySegment>>();
			List<Curve> list2 = new List<Curve>();
			foreach (BoundarySegment segment in enumerable)
			{
				if (segment.GetElement(document) != null)
				{
					Type type = segment.GetElement(document).GetType();
					ModelCurve modelCurve = segment.GetElement(document) as ModelCurve;
					if ((typeof(Wall) == type || modelCurve != null) && segment.GetCurve().Length > YJKArch.AreaSet.Common.mmToFeet(5.0))
					{
						list2.Add(segment.GetCurve());
					}
				}
			}
			CurveLoop item = CurveLoop.Create(this.GetClosedAreaCurves(list2));
			list.Add(item);
			return list;
		}

		private List<Curve> GetClosedAreaCurves(List<Curve> wallCurves)
		{
			XYZ xyz = XYZ.Zero;
			int i = 0;
			while (i < wallCurves.Count)
			{
				int num = (i + 1) % wallCurves.Count;
				IntersectionResultArray intersectionResultArray;
				SetComparisonResult setComparisonResult = wallCurves[i].Intersect(wallCurves[num], out intersectionResultArray);
				if (8 == (int)setComparisonResult)
				{
					XYZ endPoint = wallCurves[i].GetEndPoint(0);
					XYZ endPoint2 = wallCurves[i].GetEndPoint(1);
					XYZ xyzpoint = intersectionResultArray.get_Item(0).XYZPoint;
					if (xyzpoint.DistanceTo(endPoint) <= xyzpoint.DistanceTo(endPoint2))
					{
						if (2 != intersectionResultArray.Size)
						{
							goto IL_CB;
						}
					}
				}
				else if (64 == (int)setComparisonResult)
				{
					wallCurves.RemoveAt(num);
					i--;
					if (num == 0)
					{
						i--;
					}
				}
				else if (!wallCurves[i].GetEndPoint(1).IsAlmostEqualTo(wallCurves[num].GetEndPoint(0)))
				{
					goto IL_CB;
				}
				IL_1DD:
				i++;
				continue;
				IL_CB:
				Curve curve = wallCurves[i].Clone();
				curve.MakeUnbound();
				Curve curve2 = wallCurves[num].Clone();
				curve2.MakeUnbound();
				setComparisonResult = curve.Intersect(curve2, out intersectionResultArray);
				if (4 == (int)setComparisonResult || 64 == (int)setComparisonResult)
				{
					Curve item = null;
					if (this.GetShortestCurve(wallCurves[i], wallCurves[num], ref item))
					{
						wallCurves.Insert(num, item);
						i++;
						goto IL_1DD;
					}
					wallCurves.RemoveAt(i);
					wallCurves.Insert(i, item);
					goto IL_1DD;
				}
				else
				{
					if (8 == (int)setComparisonResult)
					{
						xyz = intersectionResultArray.get_Item(0).XYZPoint;
						XYZ endPoint3 = wallCurves[i].GetEndPoint(1);
						if (2 == intersectionResultArray.Size)
						{
                            XYZ xyzpoint2 = intersectionResultArray.get_Item(1).XYZPoint;
							if (xyz.DistanceTo(endPoint3) > xyzpoint2.DistanceTo(endPoint3))
							{
								xyz = xyzpoint2;
							}
						}
						Curve item2 = this.ExtendCurve(wallCurves[i], xyz);
						wallCurves.RemoveAt(i);
						wallCurves.Insert(i, item2);
						Curve item3 = this.ExtendCurve(wallCurves[num], xyz);
						wallCurves.RemoveAt(num);
						wallCurves.Insert(num, item3);
						goto IL_1DD;
					}
					goto IL_1DD;
				}
			}
			return wallCurves;
		}

		private bool GetShortestCurve(Curve curve1, Curve curve2, ref Curve shortestCurve)
		{
			XYZ endPoint = curve1.GetEndPoint(0);
			curve1.GetEndPoint(1);
			XYZ endPoint2 = curve2.GetEndPoint(0);
			curve2.GetEndPoint(1);
			XYZ endPoint3 = curve1.GetEndPoint(1);
			XYZ endPoint4 = curve2.GetEndPoint(0);
			if (endPoint3.DistanceTo(endPoint4) * 304.8 < 0.8)
			{
				shortestCurve = Line.CreateBound(endPoint, endPoint2);
				return false;
			}
			shortestCurve = Line.CreateBound(endPoint3, endPoint4);
			return true;
		}

		private Curve ExtendCurve(Curve curve, XYZ pt)
		{
			XYZ endPoint = curve.GetEndPoint(0);
			XYZ endPoint2 = curve.GetEndPoint(1);
			double num = endPoint.DistanceTo(pt);
			double num2 = endPoint2.DistanceTo(pt);
			if (num < 1E-05 || num2 < 1E-05)
			{
				return curve;
			}
			if (num > num2)
			{
				if (curve.GetType() == typeof(Line))
				{
					return Line.CreateBound(endPoint, pt);
				}
				if (curve.GetType() == typeof(Arc))
				{
					return Arc.Create(endPoint, pt, endPoint2);
				}
			}
			else
			{
				if (curve.GetType() == typeof(Line))
				{
					return Line.CreateBound(pt, endPoint2);
				}
				if (curve.GetType() == typeof(Arc))
				{
					return Arc.Create(pt, endPoint2, endPoint);
				}
			}
			return null;
		}

		internal static ApplicationClearHeight thisApp;

		private WindowHandle m_hWndRevit;

		public bool isRun = true;

		public ClearHeightCheckFun m_fun;

		public ShowClearHeightForm m_ShowClearHeightForm;

		public ClearHeightSetForm m_ShowSetForm;

		private XYZ m_PickLastPoint;

		private List<ElementId> m_lstCurvesId = new List<ElementId>();

		private UIDocument m_uiDoc;

		private DrawJigCurve m_drawJigCurve;
	}
}
